#include <iostream>
#include <list>
#include <map>
#include <set>
#include <math.h>
#include<time.h>
using namespace std;

#define forn(i,n) for(int i=0;i<(n);i++)
#define forall(it,X) for(typeof((X).begin()) it=(X).begin();it!=(X).end();it++)
float clocklog=(float)clock()/CLOCKS_PER_SEC;

/*#define TIEMPO*/

bool mayor(int* c1, int* c2, int c){
	int n1 = 0;
	int n2 = 0;
	forn(i,c){
		if(c1[i]==1) n1++;
		if(c2[i]==1) n2++;
	}
	return (n1 > n2);
}

void imprimir(map<int,list<int> >& var,const bool* variables, int v, int c, list<int>& tautologias){
	int clausulas[c];

	forn(i,c) clausulas[i] = false;
	forall(t, tautologias) clausulas[*t]=true;

	forn(i,v)
		if(variables[i]==true) forall(it,var[i+1]) clausulas[*it] = true;
		else forall(it,var[-i-1]) clausulas[*it] = true;

	/* Cantidad de clausulas satisfechas */
	int n = 0;
	forn(i,c) if(clausulas[i]) n++;
	cout << n << endl;

	/* Clausulas satisfechas */
	cout << "C";
	forn(i,c) if(clausulas[i]) cout << " " << i+1;
	cout << endl;

	/* Variables verdaderas */
	cout << "V";
	forn(i,v) if(variables[i]) cout << " " << i+1;
	cout << endl;
}

int clausulas_sat(map<int,list<int> >& var,const bool*variables, int v, int c){
	int clausulas[c];
	forn(i,c) clausulas[i] = false;
	forn(i,v)
		if(variables[i]==true) forall(it,var[i+1]) clausulas[*it] = true;
		else forall(it,var[-i-1]) clausulas[*it] = true;
	int cs = 0; forn(i,c) if(clausulas[i]) cs++;
	return cs;
}

int clausulas_insat(const bool*variables, int iter, const list<int>* clausulas, int c){
	int res;
	forn(i,c){
		bool sat = false;
		forall(it,clausulas[i]){
			if( (*it > iter) || (*it < -iter) || ( *it<0 && !variables[*it] ) || (*it>0 && variables[*it]) ){
				sat = true;
				break;
			}
		}
		if(!sat) res++;
	}
	return res;
}

void maxsat( map<int, list<int> > var, const list<int>* clausulas, bool* variables, int v, int c, int it, bool* max, int& maxcs){
	if(it<v){ // Pruebo con esta variable en false y en true

		variables[it] = false;

		if(c-maxcs < clausulas_insat(variables,it,clausulas,c)) maxsat(var, clausulas, variables, v, c, it+1, max, maxcs);

		variables[it] = true;
		if(c-maxcs < clausulas_insat(variables,it,clausulas,c)) maxsat(var, clausulas, variables, v, c, it+1, max, maxcs);

	}else{ // Complete una solucion :) Es mejor que la que tenia?
		int cs = clausulas_sat(var, variables, v, c);
		if(cs>maxcs){
			forn(i,v) max[i]=variables[i];
			maxcs=cs;
		}
	}
}

int main(){
	int contador_instancia=0;
	int c; int v;

#ifdef TIEMPO
	int caso = 1;
#endif

	while( cin >> c && cin >> v && c!=-1 && v!=-1 ){
		contador_instancia++;
		//clog << endl << "--> corriendo instancia nº " << contador_instancia << "..      ";

		/* Leo la entrada. Guardo para cada variable,
		 * la lista de clausulas a la que pertenece.
		 * Las variables estan organizadas en un arreglo */

		map<int,list<int> > var;
		list<int> clausulas[c];
		
		list<int> tautologias; //tautologias que leo en la entrada, hay que imprimirlas como satisfechas..

		/* Por cada linea 'i' que representa una clausula */
		forn(i,c){
			set<int> clausula;
			bool tautologia = false;
			int j; cin >> j;

			/* Por cada variable 'k' de las 'j'
			 * pertenecientes a la clausula 'i' */
			forn(l,j){
				int k; cin >> k;

				/* chequeo si es una tautologia */
				if(clausula.count(-k)){
					//cerr << i << " es tautologia!" << endl;
					tautologia = true;
				}
				clausula.insert(k);
			}

			/* Si no es una tautologia, inserto la clausula en la estructura de datos */
			if(!tautologia){
				forall(it,clausula){
					var[*it].push_back(i);
					clausulas[i].push_back(*it);
				}
			}
			else tautologias.push_back(i);
		}

		/* Algoritmo */

#ifdef TIEMPO
		clock_t t = clock();
#endif

		bool* variables = new bool[v];
		bool* max = new bool[v]; int maxcs = -1;

		maxsat(var,clausulas,variables,v,c,0,max,maxcs);

#ifdef TIEMPO

		t = clock() - t;

		cout << "caso: " << caso << endl;
		clog << 1000*(float)t/CLOCKS_PER_SEC << endl;

		caso++;
#endif
#ifndef TIEMPO
		imprimir(var,max,v,c,tautologias);
#endif
	}

	return 0;
}
